/// **************************************************************************************************
/// "Copyright (c) 2007 Sai Panyam, Inc.  All rights reserved."
/// **************************************************************************************************
/// Component Name   :	TextileParser, Member of System72.NTextile 
/// Description      :	TextileParser parses and delegates the various allowed modifiers to generate output
/// Author           :	Sai Panyam
/// Creation Date    :	November 09 2007
/// Modified Date    :              
/// Modified By      :
/// **************************************************************************************************
using System;
using System.Text.RegularExpressions;

namespace System72.NTextile
{
    public class TextileParser
    {
        #region Private Variables
        /// <summary>
        /// Class variable for holding original text
        /// </summary>
        private string m_originalText;

        private ModifierCollection m_modifiers;
        private AttributeCollection m_attributes;
        private AlignmentCollection m_alignments;
        private PunctuationCollection m_punctuations;

        //Attributes Modifiers Configuration
        private bool m_allowClassAttribute;
        private bool m_allowClassIdAttribute;
        private bool m_allowIdAttribute;
        private bool m_allowStyleAttribute;
        private bool m_allowLanguageAttribute;
        
        //Alignment Modifiers Configuration
        private bool m_allowRightAlignment;
        private bool m_allowLeftAlignment;
        private bool m_allowCenterAlignment;
        private bool m_allowJustifyAlignment;
        
        //Phrase Modifiers Configuration
        private bool m_allowEmphasisModifier;
        private bool m_allowStrongModifier;
        private bool m_allowCitationModifier;
        private bool m_allowDeletedTextModifier;
        private bool m_allowInsertedTextModifier;
        private bool m_allowSuperscriptModifier;
        private bool m_allowSubscriptModifier;
        private bool m_allowSpanModifier;
        private bool m_allowBoldModifier;
        private bool m_allowItalicsModifier;

        //Block Modifiers Configuration
        private bool m_allowHeaderModifier;
        private bool m_allowBlockquoteModifier;
        private bool m_allowParagraphModifier;
        private bool m_allowBlockcodeModifier;
        private bool m_allowPreformatModifier;
        private bool m_allowNoTextileModifier;

        //Punctuation Modifiers Configuration
        private bool m_allowDoubleQuotesPunctuation;
        private bool m_allowSingleQuotesPunctuation;
        private bool m_allowEmDashPunctuation;
        private bool m_allowEnDashPunctuation;
        private bool m_allowDimensionPunctuation;
        private bool m_allowTrademarkPunctuation;
        private bool m_allowCopyrightPunctuation;
        private bool m_allowRegisteredPunctuation;
        private bool m_allowEllipsesPunctuation;

        //Other Modifiers Configuration
        private bool m_allowLinkModifier;
        private bool m_allowAcronymModifier;
        private bool m_allowImageModifier;
        private bool m_allowFootnoteModifier;
        private bool m_allowFootnoteRefModifier;
        private bool m_allowNumericListModifier;
        private bool m_allowBulletedListModifier;
        private bool m_allowImageLinkModifier;

        #endregion

        #region Constructors
        /// <summary>
        /// 
        /// </summary>
        /// <param name="originalText"></param>
        public TextileParser(string originalText)
        {
            m_originalText = originalText;
        }

        #endregion
        
        #region Public Properties

        #region Main Properties

        /// <summary>
        /// Original text property
        /// </summary>
        public string OriginalText
        {
            get
            {
                return m_originalText;
            }
            set
            {
                m_originalText = value;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public ModifierCollection Modifiers
        {
            get
            {
                return m_modifiers;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public AttributeCollection Attributes
        {
            get
            {
                return m_attributes ;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public AlignmentCollection Alignments
        {
            get
            {
                return m_alignments;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public PunctuationCollection Punctuations
        {
            get { return m_punctuations; }
        }

        #endregion

        #region Phrase Modifiers
        /// <summary>
        /// 
        /// </summary>
        public bool AllowEmphasisModifier
        {
            get { return m_allowEmphasisModifier; }
            set
            {
                m_allowEmphasisModifier = value;
                PhraseModifier emphasisModifier = new PhraseModifier(PhraseModifierType.Emphasis);
                synchModifierCollection(emphasisModifier,m_allowEmphasisModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowStrongModifier
        {
            get { return m_allowStrongModifier; }
            set
            {
                m_allowStrongModifier = value;
                PhraseModifier strongModifier = new PhraseModifier(PhraseModifierType.Strong);
                synchModifierCollection(strongModifier,m_allowStrongModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowCitationModifier
        {
            get { return m_allowCitationModifier; }
            set
            {
                m_allowCitationModifier = value;
                PhraseModifier citationModifier = new PhraseModifier(PhraseModifierType.Citation);
                synchModifierCollection(citationModifier,m_allowCitationModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowDeletedTextModifier
        {
            get { return m_allowDeletedTextModifier; }
            set
            {
                m_allowDeletedTextModifier = value;
                PhraseModifier deletedTextModifier = new PhraseModifier(PhraseModifierType.DeletedText);
                synchModifierCollection(deletedTextModifier,m_allowDeletedTextModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowInsertedTextModifier
        {
            get { return m_allowInsertedTextModifier; }
            set
            {
                m_allowInsertedTextModifier = value;
                PhraseModifier insertedTextModifier = new PhraseModifier(PhraseModifierType.InsertedText);
                synchModifierCollection(insertedTextModifier,m_allowInsertedTextModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowSuperscriptModifier
        {
            get { return m_allowSuperscriptModifier; }
            set
            {
                m_allowSuperscriptModifier = value;
                PhraseModifier superScriptModifier = new PhraseModifier(PhraseModifierType.SuperScript);
                synchModifierCollection(superScriptModifier,m_allowSuperscriptModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowSubscriptModifier
        {
            get { return m_allowSubscriptModifier; }
            set
            {
                m_allowSubscriptModifier = value;
                PhraseModifier subScriptModifier = new PhraseModifier(PhraseModifierType.SubScript);
                synchModifierCollection(subScriptModifier,m_allowSubscriptModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowSpanModifier
        {
            get { return m_allowSpanModifier; }
            set
            {
                m_allowSpanModifier = value;
                PhraseModifier spanModifier = new PhraseModifier(PhraseModifierType.Span);
                synchModifierCollection(spanModifier,m_allowSpanModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowBoldModifier
        {
            get { return m_allowBoldModifier; }
            set
            {
                m_allowBoldModifier = value;
                PhraseModifier boldModifier = new PhraseModifier(PhraseModifierType.Bold);
                synchModifierCollection(boldModifier,m_allowBoldModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowItalicsModifier
        {
            get { return m_allowItalicsModifier; }
            set
            {
                m_allowItalicsModifier = value;
                PhraseModifier italicsModifier = new PhraseModifier(PhraseModifierType.Italics);
                synchModifierCollection(italicsModifier, m_allowItalicsModifier);
            }
        }

        #endregion

        #region Block Modifiers
        /// <summary>
        /// 
        /// </summary>
        public bool AllowHeaderModifier
        {
            get { return m_allowHeaderModifier; }
            set
            {
                m_allowHeaderModifier = value;
                BlockModifier heading1 = new BlockModifier(BlockModifierType.Header1);
                BlockModifier heading2 = new BlockModifier(BlockModifierType.Header2);
                BlockModifier heading3 = new BlockModifier(BlockModifierType.Header3);
                BlockModifier heading4 = new BlockModifier(BlockModifierType.Header4);
                BlockModifier heading5 = new BlockModifier(BlockModifierType.Header5);
                BlockModifier heading6 = new BlockModifier(BlockModifierType.Header6);
                synchModifierCollection(heading1,m_allowHeaderModifier,m_alignments);
                synchModifierCollection(heading2, m_allowHeaderModifier, m_alignments);
                synchModifierCollection(heading3, m_allowHeaderModifier, m_alignments);
                synchModifierCollection(heading4, m_allowHeaderModifier, m_alignments);
                synchModifierCollection(heading5, m_allowHeaderModifier, m_alignments);
                synchModifierCollection(heading6, m_allowHeaderModifier, m_alignments);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowBlockquoteModifier
        {
            get { return m_allowBlockquoteModifier; }
            set
            {
                m_allowBlockquoteModifier = value;
                BlockModifier blockQuoteModifier = new BlockModifier(BlockModifierType.Blockquote);
                synchModifierCollection(blockQuoteModifier, m_allowBlockquoteModifier, m_alignments);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowParagraphModifier
        {
            get { return m_allowParagraphModifier; }
            set
            {
                m_allowParagraphModifier = value;
                BlockModifier paragraphModifier = new BlockModifier(BlockModifierType.Paragraph);
                synchModifierCollection(paragraphModifier, m_allowParagraphModifier, m_alignments);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowBlockcodeModifier
        {
            get { return m_allowBlockcodeModifier; }
            set
            {
                m_allowBlockcodeModifier = value;
                BlockModifier blockCodeModifier = new BlockModifier(BlockModifierType.Blockcode);
                synchModifierCollection(blockCodeModifier, m_allowBlockcodeModifier, m_alignments);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowPreformatModifier
        {
            get { return m_allowPreformatModifier; }
            set
            {
                m_allowPreformatModifier = value;
                BlockModifier preformatModifier = new BlockModifier(BlockModifierType.Preformat);
                synchModifierCollection(preformatModifier, m_allowPreformatModifier, m_alignments);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowNoTextileModifier
        {
            get { return m_allowNoTextileModifier; }
            set
            {
                m_allowNoTextileModifier = value;
                BlockModifier noTextileModifier = new BlockModifier(BlockModifierType.NoTextile);
                synchModifierCollection(noTextileModifier,m_allowNoTextileModifier,m_alignments);
            }
        }

        #endregion

        #region Other Modifiers
        /// <summary>
        /// 
        /// </summary>
        public bool AllowLinkModifier
        {
            get { return m_allowLinkModifier; }
            set
            {
                m_allowLinkModifier = value;
                LinkModifier linkModifier = new LinkModifier();
                synchModifierCollection(linkModifier,m_allowLinkModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowAcronymModifier
        {
            get { return m_allowAcronymModifier; }
            set
            {
                m_allowAcronymModifier = value;
                AcronymModifier acronymModifier = new AcronymModifier();
                synchModifierCollection(acronymModifier,m_allowAcronymModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowImageModifier
        {
            get { return m_allowImageModifier; }
            set
            {
                m_allowImageModifier = value;
                ImageModifier imageModifier = new ImageModifier();
                synchModifierCollection(imageModifier,m_allowImageModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowFootnoteModifier
        {
            get { return m_allowFootnoteModifier; }
            set
            {
                m_allowFootnoteModifier = value;
                FootnoteModifier footnoteModifier = new FootnoteModifier();
                synchModifierCollection(footnoteModifier, m_allowFootnoteModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowFootnoteRefModifier
        {
            get { return m_allowFootnoteRefModifier; }
            set
            {
                m_allowFootnoteRefModifier = value;
                FootnoteRefModifier footnoteRefModifier = new FootnoteRefModifier();
                synchModifierCollection(footnoteRefModifier, m_allowFootnoteRefModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowNumericListModifier
        {
            get { return m_allowNumericListModifier; }
            set
            {
                m_allowNumericListModifier = value;
                ListModifier numericListModifier = new ListModifier(ListModifierType.NumericList);
                synchModifierCollection(numericListModifier, m_allowNumericListModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowBulletedListModifier
        {
            get { return m_allowBulletedListModifier; }
            set
            {
                m_allowBulletedListModifier = value;
                ListModifier bulletedListModifier = new ListModifier(ListModifierType.BulletedList);
                synchModifierCollection(bulletedListModifier, m_allowBulletedListModifier);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowImageLinkModifier
        {
            get { return m_allowImageLinkModifier; }
            set
            {
                m_allowImageLinkModifier = value;
                ImageLinkModifier imageLinkModifier = new ImageLinkModifier();
                synchModifierCollection(imageLinkModifier,m_allowImageLinkModifier);
            }
        }

        #endregion
        
        #region Punctuations
        /// <summary>
        /// 
        /// </summary>
        public bool AllowDoubleQuotesPunctuation
        {
            get { return m_allowDoubleQuotesPunctuation; }
            set
            {
                m_allowDoubleQuotesPunctuation = value;
                Punctuation openDoubleQuote = new Punctuation(PunctuationType.OpenDoubleQuote);
                Punctuation closeDoubleQuote = new Punctuation(PunctuationType.CloseDoubleQuote);
                synchPunctuationCollection(openDoubleQuote,m_allowDoubleQuotesPunctuation);
                synchPunctuationCollection(closeDoubleQuote, m_allowDoubleQuotesPunctuation);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowSingleQuotesPunctuation
        {
            get { return m_allowSingleQuotesPunctuation; }
            set
            {
                m_allowSingleQuotesPunctuation = value;
                Punctuation openSingleQuote = new Punctuation(PunctuationType.OpenSingleQuote);
                Punctuation closeSingleQuote = new Punctuation(PunctuationType.CloseSingleQuote);
                synchPunctuationCollection(openSingleQuote, m_allowSingleQuotesPunctuation);
                synchPunctuationCollection(closeSingleQuote, m_allowSingleQuotesPunctuation);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowEmDashPunctuation
        {
            get { return m_allowEmDashPunctuation; }
            set
            {
                m_allowEmDashPunctuation = value;
                Punctuation emDash = new Punctuation(PunctuationType.EmDash);
                synchPunctuationCollection(emDash, m_allowEmDashPunctuation);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowEnDashPunctuation
        {
            get { return m_allowEnDashPunctuation; }
            set
            {
                m_allowEnDashPunctuation = value;
                Punctuation enDash = new Punctuation(PunctuationType.EnDash);
                synchPunctuationCollection(enDash, m_allowEnDashPunctuation);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowDimensionPunctuation
        {
            get { return m_allowDimensionPunctuation; }
            set
            {
                m_allowDimensionPunctuation = value;
                Punctuation dimension = new Punctuation(PunctuationType.Dimension);
                synchPunctuationCollection(dimension, m_allowDimensionPunctuation);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowTrademarkPunctuation
        {
            get { return m_allowTrademarkPunctuation; }
            set
            {
                m_allowTrademarkPunctuation = value;
                Punctuation trademark = new Punctuation(PunctuationType.Trademark);
                synchPunctuationCollection(trademark, m_allowTrademarkPunctuation);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowCopyrightPunctuation
        {
            get { return m_allowCopyrightPunctuation; }
            set
            {
                m_allowCopyrightPunctuation = value;
                Punctuation copyright = new Punctuation(PunctuationType.Copyright);
                synchPunctuationCollection(copyright, m_allowCopyrightPunctuation);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowRegisteredPunctuation
        {
            get { return m_allowRegisteredPunctuation; }
            set
            {
                m_allowRegisteredPunctuation = value;
                Punctuation registered = new Punctuation(PunctuationType.Registered);
                synchPunctuationCollection(registered, m_allowRegisteredPunctuation);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowEllipsesPunctuation
        {
            get { return m_allowEllipsesPunctuation; }
            set
            {
                m_allowEllipsesPunctuation = value;
                Punctuation ellipses = new Punctuation(PunctuationType.Ellipses);
                synchPunctuationCollection(ellipses, m_allowEllipsesPunctuation);
            }
        }

        #endregion
        
        #region Attributes
        /// <summary>
        /// 
        /// </summary>
        public bool AllowClassAttribute
        {
            get { return m_allowClassAttribute; }
            set
            {
                m_allowClassAttribute = value;
                Attribute cssClassAttribute = new Attribute(AttributeType.Class);
                synchAttributeCollection(cssClassAttribute,m_allowClassAttribute);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowClassIdAttribute
        {
            get { return m_allowClassIdAttribute; }
            set
            {
                m_allowClassIdAttribute = value;
                Attribute classIdAttribute = new Attribute(AttributeType.ClassID);
                synchAttributeCollection(classIdAttribute,m_allowClassIdAttribute);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowIdAttribute
        {
            get { return m_allowIdAttribute; }
            set
            {
                m_allowIdAttribute = value;
                Attribute idAttribute = new Attribute(AttributeType.ID);
                synchAttributeCollection(idAttribute,m_allowIdAttribute);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowStyleAttribute
        {
            get { return m_allowStyleAttribute; }
            set
            {
                m_allowStyleAttribute = value;
                Attribute styleAttribute = new Attribute(AttributeType.Style);
                synchAttributeCollection(styleAttribute,m_allowStyleAttribute);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowLanguageAttribute
        {
            get { return m_allowLanguageAttribute; }
            set
            {
                m_allowLanguageAttribute = value;
                Attribute languageAttribute = new Attribute(AttributeType.Language);
                synchAttributeCollection(languageAttribute,m_allowLanguageAttribute);
            }
        }

        #endregion
        
        #region Alignments
        /// <summary>
        /// 
        /// </summary>
        public bool AllowRightAlignment
        {
            get { return m_allowRightAlignment; }
            set
            {
                m_allowRightAlignment = value;
                Alignment rightAlignment = new Alignment(AlignmentType.Right);
                synchAlignmentCollection(rightAlignment,m_allowRightAlignment);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowLeftAlignment
        {
            get { return m_allowLeftAlignment; }
            set
            {
                m_allowLeftAlignment = value;
                Alignment leftAlignment = new Alignment(AlignmentType.Left);
                synchAlignmentCollection(leftAlignment,m_allowLeftAlignment);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowCenterAlignment
        {
            get { return m_allowCenterAlignment; }
            set
            {
                m_allowCenterAlignment = value;
                Alignment centerAlignment = new Alignment(AlignmentType.Center);
                synchAlignmentCollection(centerAlignment,m_allowCenterAlignment);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool AllowJustifyAlignment
        {
            get { return m_allowJustifyAlignment; }
            set
            {
                m_allowJustifyAlignment = value;
                Alignment justifyAlignment = new Alignment(AlignmentType.Justify);
                synchAlignmentCollection(justifyAlignment,m_allowJustifyAlignment);
            }
        }
        
        #endregion
        
        #endregion

        #region Public Methods
        /// <summary>
        /// Method that parses and formats the original text into the corressponding HTML.
        /// </summary>
        /// <returns>The textile parsed and formatted HTML from the original text passed in.</returns>
        public string GenerateXHTML()
        {
            //Take a copy of the original text.
            string modifiedText = m_originalText;
            //First sort the modifier list as per Parse Order
            //Because we need to control the sequence in which the modifiers are applied
            //For e.g. ...
            m_modifiers.Sort(new ModifierParseOrderComparator());
            //Wrap the final modified text into paragraphs for each line
            string paragraphedText = String.Empty;
            string separator = Environment.NewLine + Environment.NewLine;
            string[] paragraphs = Regex.Split(modifiedText, separator, RegexOptions.Multiline);
            if (paragraphs != null && paragraphs.Length > 0)
            {
                for (int index = 0; index < paragraphs.Length; index++)
                {
                    bool noParagraphTag = false;
                    string paragraphText = paragraphs[index];
                    //Remove leading and trailing spaces
                    paragraphText = paragraphText.Trim();
                    bool matchSucceeded = false;
                    //Do the Inner HTML first
                    if (m_modifiers != null && m_modifiers.Count > 0 && paragraphText!=String.Empty)
                    {
                        ModifierCollection excludeModifierList = new ModifierCollection();
                        
                        foreach (IModifier modifier in m_modifiers)
                        {
                            modifier.Success = false;
                            paragraphText = modifier.GetXHTML(paragraphText, excludeModifierList);
                            if (modifier.Success)                            
                            {
                                matchSucceeded = true;
                                if (modifier.Type == ModifierType.Footnote || modifier.Type == ModifierType.Header1 || modifier.Type == ModifierType.Header2 || modifier.Type == ModifierType.Header3 || modifier.Type == ModifierType.Header4 || modifier.Type == ModifierType.Header5 || modifier.Type == ModifierType.Header6 || modifier.Type == ModifierType.Blockquote || modifier.Type == ModifierType.Paragraph || modifier.Type == ModifierType.NumericList || modifier.Type == ModifierType.BulletedList)
                                {
                                    noParagraphTag = true;
                                }
                                if (modifier.Type==ModifierType.Blockcode || modifier.Type ==ModifierType.Preformat || modifier.Type ==ModifierType.NoTextile)
                                {
                                    noParagraphTag = true;
                                    excludeModifierList=new ModifierCollection();
                                    excludeModifierList.Add(new PhraseModifier(PhraseModifierType.Bold));
                                    excludeModifierList.Add(new PhraseModifier(PhraseModifierType.Citation));
                                    excludeModifierList.Add(new PhraseModifier(PhraseModifierType.DeletedText));
                                    excludeModifierList.Add(new PhraseModifier(PhraseModifierType.Emphasis));
                                    excludeModifierList.Add(new PhraseModifier(PhraseModifierType.InsertedText));
                                    excludeModifierList.Add(new PhraseModifier(PhraseModifierType.Italics));
                                    excludeModifierList.Add(new PhraseModifier(PhraseModifierType.Span));
                                    excludeModifierList.Add(new PhraseModifier(PhraseModifierType.Strong));
                                    excludeModifierList.Add(new PhraseModifier(PhraseModifierType.SubScript));
                                    excludeModifierList.Add(new PhraseModifier(PhraseModifierType.SuperScript));
                                    excludeModifierList.Add(new AcronymModifier());
                                    excludeModifierList.Add(new ImageModifier());
                                    excludeModifierList.Add(new LinkModifier());
                                    excludeModifierList.Add(new ListModifier(ListModifierType.BulletedList));
                                    excludeModifierList.Add(new ListModifier(ListModifierType.NumericList));
                                    excludeModifierList.Add(new ImageLinkModifier());
                                    excludeModifierList.Add(new FootnoteModifier());
                                    excludeModifierList.Add(new FootnoteRefModifier());
                                }
                            }
                        }
                    }
                    //If at least one of the modifiers succeeded then we don't parse for punctuation
                    //As each modifiers handles the punctuation processing itself.
                    if (!matchSucceeded)
                    {
                        paragraphText = parseForPunctuation(paragraphText);
                    }
                    
                    paragraphText = paragraphText.Trim();//Trim any spaces if left.
                    if (paragraphText!=String.Empty)
                    {
                        //Space XHTML ouput with new lines between each paragraph
                        if (noParagraphTag)
                        {
                            paragraphedText += paragraphText + Environment.NewLine + Environment.NewLine;
                        }
                        else
                        {
                            //replace new line with <br/> character
                            paragraphText = paragraphText.Replace(Environment.NewLine, "<br/>");
                            paragraphedText += Util.GetElementMarkUp(paragraphText, "p", String.Empty) + Environment.NewLine + Environment.NewLine;
                        }
                    }
                }
            }
            if (paragraphedText != String.Empty)
            {
                modifiedText = paragraphedText;
            }
            return modifiedText;
        }
        
        #endregion

        #region Private Helper Methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <param name="allow"></param>
        private void synchModifierCollection(IModifier item,bool allow)
        {
            if(m_modifiers==null)
            {
                m_modifiers =new ModifierCollection();
            }
            if (allow && !(m_modifiers.ContainsModifier(item)))
            {
                item.SupportedAttributes = m_attributes;
                item.SupportedPunctuations = m_punctuations;
                m_modifiers.Add(item);
            }
            else
            {
                m_modifiers.Remove(item);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="blockModifier"></param>
        /// <param name="allow"></param>
        /// <param name="alignments"></param>
        private void synchModifierCollection(BlockModifier blockModifier,bool allow,AlignmentCollection alignments)
        {
            blockModifier.SupportedAlignments = alignments;
            synchModifierCollection(blockModifier, allow);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <param name="allow"></param>
        private void synchAlignmentCollection(Alignment item,bool allow)
        {
            if(m_alignments==null)
            {
                m_alignments = new AlignmentCollection();
            }
            if (allow && !(m_alignments.ContainsAlignment(item)))
            {
                m_alignments.Add(item);
            }
            else
            {
                m_alignments.Remove(item);
            }
            if (m_modifiers!=null && m_modifiers.Count>0)
            {
                foreach(IModifier modifier in m_modifiers)
                {
                    if(modifier is BlockModifier)
                    {
                        BlockModifier blockModifier = modifier as BlockModifier;
                        blockModifier.SupportedAlignments = m_alignments;
                    }
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <param name="allow"></param>
        private void synchAttributeCollection(Attribute item,bool allow)
        {
            if(m_attributes==null)
            {
                m_attributes = new AttributeCollection();
            }
            if (allow && !(m_attributes.ContainsAttribute(item)))
            {
                m_attributes.Add(item);
            }
            else
            {
                m_attributes.Remove(item);
            }
            if (m_modifiers != null && m_modifiers.Count > 0)
            {
                foreach (IModifier modifier in m_modifiers)
                {
                    modifier.SupportedAttributes = m_attributes;
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <param name="allow"></param>
        private void synchPunctuationCollection(Punctuation item, bool allow)
        {
            if (m_punctuations == null)
            {
                m_punctuations = new PunctuationCollection();
            }
            if (allow && !(m_punctuations.ContainsPunctuation(item)))
            {
                m_punctuations.Add(item);
            }
            else
            {
                m_punctuations.Remove(item);
            }
            if (m_modifiers != null && m_modifiers.Count > 0)
            {
                foreach (IModifier modifier in m_modifiers)
                {
                    modifier.SupportedPunctuations = m_punctuations;
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private string parseForPunctuation(string text)
        {
            if (m_punctuations != null && m_punctuations.Count > 0)
            {
                foreach (Punctuation punctuation in m_punctuations)
                {
                    text = punctuation.GetModifiedText(text);
                }
            }
            return text;
        }

        #endregion

    }
}
